home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Screenblankers / FT / main.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  19KB  |  834 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /*                    F l y i n g   T o a s t e r s                            */
  4. /*                                                                            */
  5. /*                                                                            */
  6. /*                                                                            */
  7. /*--------------------------------------------------------------------------*/
  8. /*    MAIN.c                                                                    */
  9. /*--------------------------------------------------------------------------*/
  10.  
  11. #define    MAIN_C
  12.  
  13. #if ! defined(HEADER_PROCOMPILED)
  14. # include    "include.h"
  15. #endif
  16. #include    "ft.h"
  17. #include    "main.h"
  18.  
  19.  
  20.  
  21.  
  22.  
  23. /*--------------------------------------------------------------------------
  24.                                 G L O B A L S
  25.   --------------------------------------------------------------------------*/
  26. BOOLEAN    volatile    blanked = FALSE,
  27.                     prefs_open = FALSE;
  28. BOOLEAN    initial_popup = FALSE;
  29. UCHAR    *ver = VERSIONSTRING,
  30.         **tooltypes;
  31. UINT    volatile nr_objects;
  32. ULONG    volatile    timeout_ticks,
  33.                     delay_rate,
  34.                     priority;
  35. LONG    volatile    mouse_timeout;
  36. enum    CORNER volatile    csleep,
  37.                         cnever;
  38. UCHAR    *blank_key,
  39.         *popup_key;
  40. struct    Library *GadToolsBase,
  41.                 *CxBase,
  42.                 *IconBase;
  43. struct    Task    *main_task;
  44. CxObj    *hotkeyfilter,
  45.         *broker;
  46. struct    MsgPort *ft_port,
  47.                 *cxport;
  48. struct    object  ft[OBJECTMAX];
  49.  
  50. struct    NewBroker newbroker = {
  51.     NB_VERSION,
  52.     PROG_NAME,
  53.     PROG_TITLE,
  54.     PROG_DESCR,
  55.     NBU_NOTIFY | NBU_UNIQUE,
  56.     COF_SHOW_HIDE,
  57.     0,NULL,0
  58.     };
  59. struct    sequence *seq_list[] = {
  60.     NULL,                                            // free flight
  61.     &default_seq,
  62.     &loop_seq,
  63.     &face_seq
  64.     };
  65.  
  66.                                                     // detach code
  67. LONG    _stack = 2048L;
  68. UCHAR    *_procname = PROG_NAME;
  69. LONG    _priority = 0L;
  70. LONG    _BackGroundIO = 1L;
  71. GLOBAL    BPTR    _Backstdout;
  72.  
  73.  
  74. /*--------------------------------------------------------------------------*/
  75. /*    init_ftmsg                                                                */
  76. /*--------------------------------------------------------------------------*/
  77. struct ft_msg * init_ftmsg(enum BLANKERACTION action)
  78.     {
  79.     struct    ft_msg    *ft_msg;
  80.  
  81.  
  82.     if ((ft_msg = (struct ft_msg *) calloc(1,sizeof(*ft_msg))) != NULL) {
  83.         ft_msg->ftm_msg.mn_Node.ln_Type = NT_MESSAGE;
  84.         ft_msg->ftm_msg.mn_Length = sizeof(*ft_msg);
  85.         ft_msg->ftm_action = action;
  86.         }
  87.     return(ft_msg);
  88.  
  89.     }    /* init_ftmsg */
  90.  
  91.  
  92.  
  93.  
  94. /*--------------------------------------------------------------------------*/
  95. /*    mouse_in_corner                                                            */
  96. /*--------------------------------------------------------------------------*/
  97. LOCAL BOOLEAN mouse_in_corner(enum CORNER corner)
  98.     {
  99.     INT        mx,my,
  100.             x,y,
  101.             w,h;
  102.     ULONG    ilock;
  103.  
  104.  
  105.     if (corner == CO_DISABLED)
  106.         return(FALSE);
  107.  
  108.     ilock = LockIBase(0L);
  109.     mx = IntuitionBase->MouseX;
  110.     my = IntuitionBase->MouseY;
  111.     x = IntuitionBase->ActiveScreen->LeftEdge;
  112.     y = IntuitionBase->ActiveScreen->TopEdge;
  113.     w = IntuitionBase->ActiveScreen->Width - MOUSE_WIDTH;
  114.     h = IntuitionBase->ActiveScreen->Height - MOUSE_HEIGHT;
  115.     UnlockIBase(ilock);
  116.  
  117.     switch (corner) {
  118.         case CO_TOPLEFT:
  119.             return((BOOLEAN) (mx <= (x + MOUSE_WIDTH) && my <= (y + MOUSE_HEIGHT)));
  120.             break;
  121.  
  122.         case CO_TOPRIGHT:
  123.             return((BOOLEAN) (mx >= (x + w) && my <= (y + MOUSE_HEIGHT)));
  124.             break;
  125.  
  126.         case CO_BOTTOMLEFT:
  127.             return((BOOLEAN) (mx <= (x + MOUSE_WIDTH) && my >= (y + h)));
  128.             break;
  129.  
  130.         case CO_BOTTOMRIGHT:
  131.             return((BOOLEAN) (mx >= (x + w) && my >= (y + h)));
  132.             break;
  133.         }    // switch
  134.  
  135.     }    /* mouse_in_corner */
  136.  
  137.  
  138.  
  139. /*--------------------------------------------------------------------------*/
  140. /*    dispatch_cx                                                                */
  141. /*--------------------------------------------------------------------------*/
  142. void __stdargs __saveds dispatch_cx(CxMsg *CxMessage,CxObj *CxObject)
  143.     {
  144.     static    BOOLEAN    mouse_blanked = FALSE;
  145.     static    ULONG    timer_ticks = 0L;
  146.     struct    InputEvent *event;
  147.     struct    ft_msg    *ft_msg;
  148.  
  149.  
  150.     event = (struct InputEvent *) CxMsgData(CxMessage);
  151.  
  152.     if (blanked) {
  153.         if ((event->ie_Class == IECLASS_RAWKEY && 
  154.                 (event->ie_Code & IECODE_UP_PREFIX) == 0 && 
  155.                 (event->ie_Qualifier & IEQUALIFIER_REPEAT) == 0) ||
  156.                 event->ie_Class == IECLASS_RAWMOUSE) {
  157.             timer_ticks = 0L;
  158.             mouse_blanked = FALSE;
  159.             if ((ft_msg = init_ftmsg(BA_WAIT)) != NULL)
  160.                 PutMsg(ft_port,(struct Message *) ft_msg);
  161.             }
  162.         return;
  163.         }
  164.  
  165.     if (event->ie_Class == IECLASS_TIMER) {            // process timer event
  166.         timer_ticks++;
  167.         if (timer_ticks == timeout_ticks) {
  168.             if (! mouse_in_corner(cnever) && (ft_msg = init_ftmsg(BA_BLANK)) != NULL)
  169.                 PutMsg(ft_port,(struct Message *) ft_msg);
  170.             return;
  171.             }
  172.         else if (timer_ticks == CORNER_TIMEOUT &&
  173.                 mouse_in_corner(csleep) &&
  174.                 (ft_msg = init_ftmsg(BA_BLANK)) != NULL) {
  175.             PutMsg(ft_port,(struct Message *) ft_msg);
  176.             }
  177.         else if (mouse_timeout != -1L && (LONG) timer_ticks == mouse_timeout) {
  178.             WaitTOF();
  179.             OFF_SPRITE;
  180.             custom.spr[0].dataa = 0;
  181.             custom.spr[0].datab = 0;
  182.             mouse_blanked = TRUE;
  183.             }
  184.         return;
  185.         }
  186.  
  187.     timer_ticks = 0L;                                // reset ticks
  188.     if (mouse_blanked && event->ie_Class != IECLASS_RAWKEY) {
  189.         ON_SPRITE;
  190.         mouse_blanked = FALSE;
  191.         }
  192.     else if (mouse_timeout != -1L && ! mouse_blanked && event->ie_Class == IECLASS_RAWKEY) {
  193.         WaitTOF();
  194.         OFF_SPRITE;
  195.         custom.spr[0].dataa = 0;
  196.         custom.spr[0].datab = 0;
  197.         mouse_blanked = TRUE;
  198.         }
  199.  
  200.     }    /* dispatch_cx */
  201.  
  202.  
  203. /*--------------------------------------------------------------------------*/
  204. /*    create_process                                                            */
  205. /*--------------------------------------------------------------------------*/
  206. struct Process *create_process(UCHAR *pname, void (*func) (void), BOOLEAN cli)
  207.     {
  208.     struct    TagItem tag[7];
  209.  
  210.  
  211.     tag[0].ti_Tag = NP_Entry;
  212.     tag[0].ti_Data = (Tag) func;
  213.  
  214.     tag[1].ti_Tag = NP_Name;
  215.     tag[1].ti_Data = (Tag) pname;
  216.  
  217.     tag[2].ti_Tag = NP_Output;
  218.     tag[2].ti_Data = (Tag) Open("*",MODE_NEWFILE);
  219.  
  220.     tag[3].ti_Tag = NP_Cli;
  221.     tag[3].ti_Data = (Tag) cli;
  222.  
  223.     tag[4].ti_Tag = NP_Priority;
  224.     tag[4].ti_Data = (Tag) priority;
  225.  
  226.     tag[5].ti_Tag = NP_StackSize;
  227.     tag[5].ti_Data = (Tag) 3000;
  228.     
  229.     tag[6].ti_Tag = TAG_DONE;
  230.  
  231.     return(CreateNewProc(tag));
  232.  
  233.     }    /* create_process */
  234.  
  235.  
  236.  
  237.  
  238. /*--------------------------------------------------------------------------*/
  239. /*    open_cxstuff                                                            */
  240. /*--------------------------------------------------------------------------*/
  241. BOOLEAN open_cxstuff(void)
  242.     {
  243.     CxObj    *obj;
  244.  
  245.  
  246.     if ((cxport = CreatePort(CX_PORT_NAME,0L)) == NULL) {
  247.         dbprintf("no cx port\n");
  248.         return(FALSE);
  249.         }
  250.  
  251.     newbroker.nb_Pri = 0;
  252.     newbroker.nb_Port = cxport;
  253.  
  254.     if((broker = CxBroker(&newbroker,NULL)) == NULL) {
  255.         dbprintf("no broker\n");
  256.         return(FALSE);
  257.         }
  258.  
  259.     if ((obj = HotKey(blank_key,cxport,BA_BLANK)) == NULL) {
  260.         dbprintf("cx failed (1)\n");
  261.         return(FALSE);
  262.         }
  263.     AttachCxObj(broker,obj);
  264.  
  265.     if ((obj = HotKey(popup_key,cxport,BA_POPUP_PREFS)) == NULL) {
  266.         dbprintf("cx failed (1.1)\n");
  267.         return(FALSE);
  268.         }
  269.     AttachCxObj(broker,obj);
  270.  
  271.     if ((obj = CxCustom(dispatch_cx,NULL)) == NULL) {
  272.         dbprintf("cx: no key custom\n");
  273.         return(FALSE);
  274.         }
  275.  
  276.     AttachCxObj(broker,obj);
  277.  
  278.     if (CxObjError(broker)) {
  279.         dbprintf("cx failed (4)\n");
  280.         return(FALSE);
  281.         }
  282.  
  283.     ActivateCxObj(broker,TRUE);
  284.  
  285.     return(TRUE);
  286.  
  287.     }    /* open_cxstuff */
  288.  
  289.  
  290. /*--------------------------------------------------------------------------*/
  291. /*    close_cxstuff                                                            */
  292. /*--------------------------------------------------------------------------*/
  293. void close_cxstuff(void)
  294.     {
  295.  
  296.     if (broker != NULL)
  297.         DeleteCxObjAll(broker);
  298.  
  299.     if (cxport != NULL)
  300.         DeletePort(cxport);
  301.  
  302.     }    /* close_cxstuff */
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309. /*--------------------------------------------------------------------------*/
  310. /*    open_stuff                                                                */
  311. /*--------------------------------------------------------------------------*/
  312. BOOLEAN open_stuff(UINT argc, UCHAR *argv[])
  313.     {
  314.     UCHAR    *str;
  315.     UINT    i;
  316.  
  317.  
  318.     if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",37L)) == NULL)
  319.         return(FALSE);
  320.  
  321.     if ((IntuitionBase = (struct IntuitionBase *) 
  322.             OpenLibrary("intuition.library",37L)) == NULL)
  323.         return(FALSE);
  324.  
  325.     if ((GadToolsBase = OpenLibrary("gadtools.library",37L)) == NULL)
  326.         return(FALSE);
  327.  
  328.     if ((CxBase = OpenLibrary("commodities.library",37L)) == NULL)
  329.         return(FALSE);
  330.  
  331.     if ((IconBase = OpenLibrary("icon.library",37L)) == NULL)
  332.         return(FALSE);
  333.  
  334.     tooltypes = ArgArrayInit(argc,argv);
  335.  
  336.     initial_popup = stricmp("yes",ArgString(tooltypes,CX_POPUP,DEF_CX_POPUP)) == 0;
  337.     newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY,DEF_CX_PRIORITY);
  338.     popup_key = ArgString(tooltypes, CX_POPKEY,DEF_CX_POPKEY);
  339.     blank_key = ArgString(tooltypes,CX_BLANKKEY,DEF_CX_BLANKKEY);
  340.     timeout_ticks = (ArgInt(tooltypes, TT_TIMEOUT, DEF_TIMEOUT) * TICKSPERMIN) / 60;
  341.     nr_objects = ArgInt(tooltypes, TT_NR_OBJECTS,DEF_NR_OBJECTS);
  342.     priority = ArgInt(tooltypes, TT_PRIORITY, DEF_PRIORITY);
  343.     mouse_timeout = ArgInt(tooltypes, TT_MOUSE_TIMEOUT, DEF_MOUSE_TIMEOUT);
  344.     if (mouse_timeout != -1L) 
  345.         mouse_timeout = (mouse_timeout * TICKSPERMIN) / 60;
  346.  
  347.     str = ArgString(tooltypes,TT_SPEED,DEF_SPEED);
  348.     for (i = 1; i < 4 && stricmp(str,delay_txt[i - 1]) != 0; i++)
  349.         ;
  350.     delay_rate = i;
  351.     if (delay_rate == 4)
  352.         delay_rate = 2;
  353.  
  354.     str = ArgString(tooltypes,TT_SLEEPCORNER,DEF_SLEEPCORNER);
  355.     for (i = 0; i < CO_DISABLED && stricmp(str,corner_txt[i]) != 0; i++)
  356.         ;
  357.     csleep = i;
  358.  
  359.     str = ArgString(tooltypes,TT_NEVERSLEEP,DEF_NEVERSLEEP);
  360.     for (i = 0; i < CO_DISABLED && stricmp(str,corner_txt[i]) != 0; i++)
  361.         ;
  362.     cnever = i;
  363.     if (cnever == csleep)
  364.         cnever = CO_DISABLED;
  365.  
  366.     if (! open_cxstuff())
  367.         return(FALSE);
  368.  
  369.     return(TRUE);
  370.  
  371.     }    /* open_stuff */
  372.  
  373.  
  374.  
  375. /*--------------------------------------------------------------------------*/
  376. /*    close_stuff                                                                */
  377. /*--------------------------------------------------------------------------*/
  378. void close_stuff(void)
  379.     {
  380.  
  381.     close_cxstuff();
  382.  
  383.     ArgArrayDone();
  384.  
  385.     if (IconBase != NULL)
  386.         CloseLibrary(IconBase);
  387.  
  388.     if (CxBase != NULL)
  389.         CloseLibrary(CxBase);
  390.  
  391.     if (GadToolsBase != NULL)
  392.         CloseLibrary(GadToolsBase);
  393.  
  394.     if (IntuitionBase != NULL)
  395.         CloseLibrary((struct Library *) IntuitionBase);
  396.  
  397.     if (GfxBase != NULL)
  398.         CloseLibrary((struct GfxBase *) GfxBase);
  399.  
  400.     }    /* close_stuff */
  401.  
  402.  
  403. /*--------------------------------------------------------------------------*/
  404. /*    urand                                                                    */
  405. /*--------------------------------------------------------------------------*/
  406. INT urand(INT limit)
  407.     {
  408.     static LONG random_seed = 0xDEAD0123;
  409.  
  410.     random_seed = random_seed * custom.vhposr + 0xe153766f;
  411.  
  412.     return ((INT) ((UINT) random_seed % limit));
  413.  
  414.     }    /* urand */
  415.  
  416.  
  417.  
  418.  
  419. /*--------------------------------------------------------------------------*/
  420. /*    check_collision                                                            */
  421. /*--------------------------------------------------------------------------*/
  422. INT check_collision(INT i,INT x, INT y)
  423.     {
  424.     INT        j,
  425.             jx,jy;
  426.  
  427.  
  428.     x += IM_WIDTH / 2;
  429.     y += IM_HEIGHT / 2;
  430.  
  431.     for (j = 0; j < nr_objects; j++) {
  432.         if (j != i && ft[j].delay == 0) {
  433.             jx = ft[j].x + IM_WIDTH / 2;
  434.             jy = ft[j].y + IM_HEIGHT / 2;
  435.  
  436.             if (((jx - x) * (jx - x) + (jy - y) * (jy - y)) <= (4 * IM_RADIUS * IM_RADIUS))
  437.                 return(j);
  438.             }
  439.         }
  440.     return(-1);
  441.     }    /* check_collision */
  442.  
  443.  
  444.  
  445. /*--------------------------------------------------------------------------*/
  446. /*    calc_new_pos                                                            */
  447. /*--------------------------------------------------------------------------*/
  448. void calc_new_pos(INT i)
  449.     {
  450.     INT        x,y,
  451.             c;
  452.  
  453.  
  454.     x = ft[i].x - ft[i].speed;
  455.     y = ft[i].y + 2;
  456.  
  457.     ft[i].old_x = ft[i].x;
  458.     ft[i].old_y = ft[i].y;
  459.  
  460.     if ((c = check_collision(i,x,y)) != -1) {
  461.         x = ft[i].x;
  462.         y += 2;
  463.         if ((c = check_collision(i,x,y)) != -1) {
  464.             y = ft[i].y - 4;
  465.             if ((c = check_collision(i,x,y)) != -1)
  466.                 return;
  467.             }
  468.         }
  469.  
  470.     ft[i].x = x;
  471.     ft[i].y = y;
  472.  
  473.     }    /* calc_new_pos */
  474.  
  475.  
  476.  
  477. /*--------------------------------------------------------------------------*/
  478. /*    find_launch_pos                                                            */
  479. /*--------------------------------------------------------------------------*/
  480. BOOLEAN find_launch_pos(INT i)
  481.     {
  482.     BOOLEAN    colides;
  483.     INT        j,
  484.             x,y,
  485.             ix,iy,
  486.             jx,jy;
  487.  
  488.  
  489.     x = win->Width;
  490.     y = (urand(7) - 1) * IM_HEIGHT;
  491.  
  492.     FOREVER {
  493.         if (x <= (2 * IM_WIDTH) && y <= - IM_HEIGHT)
  494.             return(FALSE);
  495.  
  496.         ix = x + IM_WIDTH / 2;
  497.         iy = y + IM_HEIGHT / 2;
  498.  
  499.         colides = FALSE;
  500.         for (j = 0; j < nr_objects && ! colides; j++) {
  501.             if (i != j) {
  502.                 jx = ft[j].x + IM_WIDTH / 2;
  503.                 jy = ft[j].y + IM_HEIGHT / 2;
  504.  
  505.                 if (((jx - ix) * (jx - ix) + (jy - iy) * (jy - iy)) <=
  506.                         (4 * IM_RADIUS * IM_RADIUS)) {
  507.                     colides = TRUE;
  508.                     }
  509.                 }
  510.             }
  511.  
  512.         if (! colides) {
  513.             ft[i].x = ft[i].old_x = x;
  514.             ft[i].y = ft[i].old_y = y;
  515.             return(TRUE);
  516.             }
  517.  
  518.         if (y > - IM_HEIGHT)
  519.             y -= IM_HEIGHT;
  520.         else
  521.             x -= IM_WIDTH;
  522.  
  523.         }
  524.     }    /* find_launch_pos */
  525.  
  526.  
  527.  
  528.  
  529. /*--------------------------------------------------------------------------*/
  530. /*    goto_next_img                                                            */
  531. /*--------------------------------------------------------------------------*/
  532. void goto_next_img(struct object *obj, struct sequence *next_seq)
  533.     {
  534.     obj->phase++;
  535.     if (obj->phase >= obj->seq->img_count) {
  536.         obj->phase = 0;
  537.         if (next_seq == NULL) {
  538.             obj->seq = obj->seq->next_sequence;
  539.             if (urand(LOOPRATE) == 0) {
  540.                 obj->rate = RATE_DEC - 1;
  541.                 obj->seq = &loop_seq;
  542.                 }
  543.             else if (urand(FACERATE) == 0) {
  544.                 obj->rate = RATE_DEC - 1;
  545.                 obj->seq = &face_seq;
  546.                 }
  547.             }
  548.         else
  549.             obj->seq = next_seq;
  550.         }
  551.     }    /* goto_next_img */
  552.  
  553.  
  554.  
  555. /*--------------------------------------------------------------------------*/
  556. /*    run_ft                                                                    */
  557. /*--------------------------------------------------------------------------*/
  558. struct ft_msg * run_ft(void)
  559.     {
  560.     INT        i;
  561.     struct    ft_msg    *ft_msg;
  562.  
  563.  
  564.     if (win != NULL)
  565.         return(NULL);
  566.  
  567.     if (! open_display()) {
  568.         close_display();
  569.         return(NULL);
  570.         }
  571.  
  572.     if (nr_objects == 0) {
  573.         ft_msg = (struct ft_msg *) WaitPort(ft_port);
  574.         close_display();
  575.         return(ft_msg);
  576.         }
  577.  
  578.     for (i = 0; i < nr_objects; i++) {
  579.         memset(&ft[i],'\0',sizeof(ft[0]));
  580.  
  581.         if (! find_launch_pos(i))
  582.             ft[i].delay = 30;
  583.         else
  584.             ft[i].delay = urand(50);
  585.         ft[i].phase = urand(IMAGEMAX);
  586.         ft[i].seq = &default_seq;
  587.         ft[i].speed = FT_SPEED;
  588.         ft[i].rate = ft[i].rate_count = FT_RATE(i);
  589.         }
  590.  
  591.     while ((ft_msg = (struct ft_msg *) GetMsg(ft_port)) == NULL ||
  592.                 ft_msg->ftm_action == BA_BLANK) {
  593.  
  594.         if (ft_msg != NULL)
  595.             free(ft_msg);
  596.  
  597.         for (i = 0; i < nr_objects; i++) {
  598.             if (ft[i].delay == 0) {
  599.                 calc_new_pos(i);
  600.  
  601.                 ft[i].rate_count -= RATE_DEC;
  602.                 if (ft[i].rate_count < 0) {
  603.                     ft[i].rate_count = ft[i].rate;
  604.                     goto_next_img(&ft[i], NULL);
  605.                     }
  606.  
  607.                 if ((ft[i].old_x != ft[i].x || ft[i].old_y != ft[i].y)) {
  608.  
  609.                     if (ft[i].y > ft[i].old_y) {
  610.                         EraseRect(win->RPort,ft[i].old_x,ft[i].old_y,
  611.                                 ft[i].old_x + IM_WIDTH,ft[i].y + 1);
  612.                         }
  613.                     if (ft[i].x < ft[i].old_x) {
  614.                         EraseRect(win->RPort,ft[i].x + IM_WIDTH - 1,ft[i].y,
  615.                                 ft[i].old_x + IM_WIDTH,ft[i].old_y + IM_HEIGHT);
  616.                         }
  617.                     }
  618.  
  619.                 DrawImage(win->RPort,ft[i].seq->img[ft[i].phase],ft[i].x,ft[i].y);
  620.  
  621.                 if (ft[i].x < - (IM_WIDTH + 1) || ft[i].y > win->Height)
  622.                     ft[i].delay = urand(50);
  623.                 }
  624.             else {
  625.                 ft[i].delay--;
  626.                 if (ft[i].delay == 0) {
  627.                     if (find_launch_pos(i)) {
  628.                         ft[i].speed = FT_SPEED;
  629.                         ft[i].rate = ft[i].rate_count = FT_RATE(i);
  630.                         }
  631.                     else
  632.                         ft[i].delay = 30;
  633.                     }
  634.                 }
  635.             }
  636.  
  637.         Delay(delay_rate);
  638.  
  639.         }
  640.  
  641.     close_display();
  642.  
  643.     return(ft_msg);
  644.  
  645.     }    /* run_ft */
  646.  
  647.  
  648.  
  649. /*--------------------------------------------------------------------------*/
  650. /*    launch_ft                                                                */
  651. /*--------------------------------------------------------------------------*/
  652. void __saveds launch_ft(void)
  653.     {
  654.     enum    BLANKERACTION    action;
  655.     struct    ft_msg    *ft_msg;
  656.  
  657.  
  658.     if ((ft_port = CreatePort(FT_PORT_NAME,NULL)) == NULL)
  659.         return;
  660.  
  661.     ft_msg = (struct ft_msg *) WaitPort(ft_port);
  662.     action = ft_msg->ftm_action;
  663.     free(ft_msg);
  664.  
  665.     FOREVER {
  666.  
  667.         blanked = FALSE;
  668.  
  669.         switch (action) {
  670.  
  671.             case BA_BLANK:
  672.                 if (! blanked) {
  673.                     blanked = TRUE;
  674.                     ft_msg = run_ft();
  675.                     }
  676.                 break;
  677.  
  678.             case BA_TERMINATE:
  679.                 DeletePort(ft_port);
  680.                 return;
  681.  
  682.             case BA_POPUP_PREFS:
  683.                 prefs_open = TRUE;
  684.                 ft_msg = open_prefs();
  685.                 prefs_open = FALSE;
  686.                 break;
  687.  
  688.             default:
  689.                 if ((ft_msg = (struct ft_msg *) GetMsg(ft_port)) == NULL)
  690.                     ft_msg = (struct ft_msg *) WaitPort(ft_port);
  691.                 break;
  692.  
  693.             }    // switch
  694.  
  695.         if (ft_msg != NULL) {
  696.             action = ft_msg->ftm_action;
  697.             free(ft_msg);
  698.             }
  699.         else
  700.             action = BA_WAIT;
  701.     
  702.         }    // FOREVER
  703.     }    /* launch_ft */
  704.  
  705.  
  706.  
  707.  
  708. /*--------------------------------------------------------------------------*/
  709. /*    main                                                                    */
  710. /*--------------------------------------------------------------------------*/
  711. void main(UINT argc, UCHAR *argv[])
  712.     {
  713.     ULONG    signal,
  714.             id,type;
  715.     CxMsg    *cxmsg;
  716.     struct    ft_msg    *ft_msg;
  717.     struct    Process *ft_proc;
  718.  
  719.  
  720.  
  721.  
  722. #if ! defined(DEBUG)
  723.  
  724.     if (! IS_KICK2_0) {
  725.         if (_Backstdout != NULL) {
  726.             Write(_Backstdout,requires_txt,strlen(requires_txt));
  727.             Close(_Backstdout);
  728.             }
  729.         return;
  730.         }
  731.  
  732.     if (_Backstdout != NULL) {
  733.         if (argv[1][0] == '?') {
  734.             Write(_Backstdout,helpstring,strlen(helpstring));
  735.             Close(_Backstdout);
  736.             return;
  737.             }
  738.         Close(_Backstdout);
  739.         }
  740. #else
  741.         if (argv[1][0] == '?') {
  742.             puts(helpstring);
  743.             return;
  744.             }
  745. #endif
  746.  
  747.     if ((main_task = FindTask(NULL)) == NULL)
  748.         return;
  749.  
  750.     if (! open_stuff(argc,argv)) {
  751.         close_stuff();
  752.         return;
  753.         }
  754.  
  755.     if ((ft_proc = create_process(FT_PROCNAME,launch_ft,FALSE)) == NULL) {
  756.         close_stuff();
  757.         return;
  758.         }
  759.  
  760.     while(FindPort(FT_PORT_NAME) == NULL)
  761.         Delay(1L);
  762.  
  763.     if (initial_popup && (ft_msg = init_ftmsg(BA_POPUP_PREFS)) != NULL)
  764.         PutMsg(ft_port,(struct Message *) ft_msg);
  765.  
  766.     do {
  767.         signal = Wait(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D| 1L << cxport->mp_SigBit);
  768.  
  769.         while ((cxmsg = (CxMsg *) GetMsg(cxport)) != NULL) {
  770.             id = CxMsgID(cxmsg);
  771.             type = CxMsgType(cxmsg);
  772.             ReplyMsg((struct Message *) cxmsg);
  773.  
  774.             switch(type) {
  775.                 case CXM_IEVENT:
  776.                     switch(id) {
  777.                         case BA_BLANK:
  778.                             if (! blanked && (ft_msg = init_ftmsg(BA_BLANK)) != NULL)
  779.                                 PutMsg(ft_port, (struct Message *) ft_msg);
  780.                             break;
  781.  
  782.                         case BA_POPUP_PREFS:
  783.                             if (! prefs_open && (ft_msg = init_ftmsg(BA_POPUP_PREFS)) != NULL) {
  784.                                 PutMsg(ft_port, (struct Message *) ft_msg);
  785.                                 }
  786.                             break;
  787.  
  788.                         }    // switch
  789.                     break;
  790.  
  791.                 case CXM_COMMAND:
  792.                     switch (id) {
  793.                         case CXCMD_DISABLE:
  794.                             ActivateCxObj(broker,FALSE);
  795.                             break;
  796.  
  797.                         case CXCMD_ENABLE:
  798.                             ActivateCxObj(broker,TRUE);
  799.                             break;
  800.  
  801.                         case CXCMD_APPEAR:
  802.                         case CXCMD_UNIQUE:
  803.                             if (! prefs_open && (ft_msg = init_ftmsg(BA_POPUP_PREFS)) != NULL) {
  804.                                 PutMsg(ft_port, (struct Message *) ft_msg);
  805.                                 }
  806.                             break;
  807.  
  808.                         case CXCMD_DISAPPEAR:
  809.                             if (prefs_open && (ft_msg = init_ftmsg(BA_WAIT)) != NULL) {
  810.                                 PutMsg(ft_port, (struct Message *) ft_msg);
  811.                                 }
  812.                             break;
  813.  
  814.                         case CXCMD_KILL:
  815.                             signal |= SIGBREAKF_CTRL_C;
  816.                             break;
  817.  
  818.                         }    // switch
  819.                     break;
  820.  
  821.                 }
  822.             }    // while
  823.         } while ((signal & (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) == 0L);
  824.  
  825.     while(FindTask(FT_PROCNAME) != NULL) {
  826.         if ((ft_msg = init_ftmsg(BA_TERMINATE)) != NULL)
  827.             PutMsg(ft_port,(struct Message *) ft_msg);
  828.         Delay(10L);
  829.         }
  830.  
  831.     close_stuff();
  832.  
  833.     }    /* main */
  834.